﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using LinkShareWpf.Commands;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Markup;
using System.Collections.ObjectModel;
using UniCT.LinkShareWpf.Interface;
using System.Collections.Specialized;
using System.Windows.Data;
using UniCT.LinkShareWpf.CommunicationChannel;
using System.Windows.Media.Imaging;
using System.IO;
using LinkShareWpf.Properties;
using UniCT.LinkShareWpf.Model;


namespace LinkShareWpf.ViewModel
{

    public partial class ShowResourceViewModel : ViewModelBase
    {

        #region Private
        private ICollectionView view;
        private ObservableCollection<Resource> allResources;
        private Resource res;
        #endregion

        #region Commmands
        public DelegateCommand MoveNextCommand { get; private set; }
        public DelegateCommand MovePreviousCommand { get; private set; }
        public DelegateCommand GoToLinkCommand { get; private set; }
        public DelegateCommand SaveCommand { get; private set; }
        public DelegateCommand DeleteCommand { get; private set; }
        #endregion

        #region Properties
        public ObservableCollection<Resource> AllResources
        {
            get { return allResources; }
            set { allResources = value; }
        }
        public Resource Resource
        {
            get { return res; }
            set { res = value; }
        }
        #endregion

        #region Events
        public event EventHandler CloseWindowRequested;
        public event EventHandler MessageBoxRequested;
        #endregion

        private Resource CurrentResource
        {
            get { return view.CurrentItem as Resource; }
        }

        public void Setting()
        {
            // Il problema nasceva perché alla creazione della vista, nello xaml il binding del comando
            // era fatto verso un DelegateCommand non istanziato ovvero posto a NULL
            // Il Setting() non sembrava aggiornare lo stato del comando che puntando a NULL
            // Non eseguiva nulla
            // Si deve trovare un modo di aggiornare il bindig una volta che il comando è istanziato
            // UpdateModel() è la soluzione :)
            MoveNextCommand = new DelegateCommand(o => MoveNext(), o => CanMoveNext());
            MovePreviousCommand = new DelegateCommand(o => MovePrevious(), o => CanMovePrevious());
            GoToLinkCommand = new DelegateCommand(o => GoToLink());
            SaveCommand = new DelegateCommand(commandParameter => Save(commandParameter), commandParameter => CanSave(commandParameter));
            DeleteCommand = new DelegateCommand(commandParameter => Delete(commandParameter));
            view = CollectionViewSource.GetDefaultView(allResources);
            view.MoveCurrentTo(res);
            UpdateModel();
        }

        // Procedura per il salvataggio di una risorsa ricevuta da remoto
        private void Save(object commandParameter)
        {
            NetResource remoteRes = commandParameter as NetResource;

            // Salvo il file dell'immmagine di locandina
            try
            {
                String pathTemp = Settings.Default.CoversPath + @"\Temp\";
                String pathCovers = Settings.Default.CoversPath + @"\";
                File.Move(pathTemp + remoteRes.CInfo.CoverName, pathCovers + remoteRes.CInfo.CoverName);
            }
            catch (Exception e)
            {
                Console.WriteLine("*** Eccezione generata da ShowResourceViewModel.Save( ... ) ***\n" + e.Message + "\n" + e.InnerException);
                return;
            }

            // Salvo la risorsa nella lista
            MyResources.Instance.Resources.Add(new Resource(remoteRes));
            MyResources.Instance.Save();

            // Richiedo l'aggiornamento al WindowHandler
            WindowHandler.Instance.UpdateRequest();

            // Richiedo alla view di notificare all'utente il salvataggio
            MessageBoxRequested(this, new MessageParameterEventArgs("La risorsa è stata salvata con successo"));
        }

        private bool CanSave(object commandParameter)
        {
            Resource remoteRes = commandParameter as Resource;

            // Verifico che tra le risorse già presenti in locale
            // non ve ne sia una avente lo stesso link di quella visualizzata
            foreach (Resource localRes in MyResources.Instance.Resources)
                if (localRes.Url.Equals(remoteRes.Url))
                    return false;
            return true;
        }

        private void Delete(object commandParameter)
        {
            // Definisco una risorsa temporanea
            Resource temp = null;
     
            // Cerco la risorsa in modo univoco tramite URL e la salvo come risorsa temporanea
            foreach (Resource myRes in MyResources.Instance.Resources)
            {
                if (CurrentResource.Url == myRes.Url)
                {
                    temp = myRes;
                    break;
                }
            }
            
            // Rimuovo la risorsa dall'oggetto ICollectionView
            (view.SourceCollection as ObservableCollection<Resource>).Remove(CurrentResource);

            // Elimino il file dell'immagine di locandina
            try
            {
                string coverPath = Settings.Default.CoversPath;
                File.Delete(coverPath + "\\" + temp.CInfo.CoverName);
            }
            catch (Exception ex)
            {
                Console.WriteLine("ShowResourceViewModel.Delete( ... ):\n" + ex.Message + "\n" + ex.InnerException);
            }

            // Elimino la risorsa dalla lista
            MyResources.Instance.Resources.Remove(temp);
            MyResources.Instance.Save();

            // Richiedo l'aggiornamento al WindowHandler
            WindowHandler.Instance.UpdateRequest();
            
            // Aggiorno la visualizzazione della finestra
            if ((view.SourceCollection as ObservableCollection<Resource>).Count == 0)
                CloseWindowRequested(this, EventArgs.Empty);
            else
            {
                res = view.CurrentItem as Resource;
                UpdateModel();
            }

            // Richiedo alla view di notificare all'utente la cancellazione
            MessageBoxRequested(this, new MessageParameterEventArgs("La risorsa è stata rimossa con successo"));

        }

        private void GoToLink()
        {
            System.Diagnostics.Process.Start("iexplore.exe", res.Url);
            MessageBox.Show("Buona visione!");
        }

        private void MoveNext()
        {
            view.MoveCurrentToNext();
            res = view.CurrentItem as Resource;
            UpdateModel();
        }

        private bool CanMoveNext()
        {
            int total = (view.SourceCollection as ObservableCollection<Resource>).Count;
            return view.CurrentPosition < total - 1;
        }

        private void MovePrevious()
        {
            view.MoveCurrentToPrevious();
            res = view.CurrentItem as Resource;
            UpdateModel();
        }

        private bool CanMovePrevious()
        {
            return view.CurrentPosition > 0;
        }

        private void UpdateModel()
        {
            OnPropertyChanged(null);
        }

        public class MessageParameterEventArgs : EventArgs
        {
            public string message;
            public MessageParameterEventArgs(String msg)
            {
                message = msg;
            }
        }
    }

  

}
